# Copyright (c) 2020 GITEE.COM All Rights Reserved.

cmake_minimum_required(VERSION 3.14)
project(git-analyze)

if(CMAKE_SOURCE_DIR STREQUAL CMAKE_BINARY_DIR AND NOT MSVC_IDE)
  message(
    FATAL_ERROR
      "In-source builds are not allowed.
CMake would overwrite the makefiles distributed with GitHook.
Please create a directory and run cmake from there, passing the path
to this source directory as the last argument.
This process created the file `CMakeCache.txt' and the directory `CMakeFiles'.
Please delete them.")
endif()

if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
  message(STATUS "No build type selected, default to Debug")
  set(CMAKE_BUILD_TYPE
      "Debug"
      CACHE STRING "Build type (default Debug)" FORCE)
  # Set the possible values of build type for cmake-gui
  set_property(
    CACHE CMAKE_BUILD_TYPE
    PROPERTY STRINGS
             "Debug"
             "Release"
             "MinSizeRel"
             "RelWithDebInfo")
endif()

set(GITANALYZE_VERSION_MAJOR 4)
set(GITANALYZE_VERSION_MINOR 0)
set(GITANALYZE_VERSION_PATCH 0)

set(PACKAGE_VERSION "${GITANALYZE_VERSION_MAJOR}.${GITANALYZE_VERSION_MINOR}.${GITANALYZE_VERSION_PATCH}")

set(CMAKE_INSTALL_RPATH "$ORIGIN/../lib")

set(CPACK_PACKAGE_NAME "git-analyze")
set(CPACK_PACKAGE_VENDOR "GITEE.COM")
set(CPACK_PACKAGE_DESCRIPTION "This is git analyze tools")
set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "GIT Analyze")
set(CPACK_PACKAGE_INSTALL_DIRECTORY "git-analyze")
set(CPACK_PACKAGE_VERSION_MAJOR ${GITANALYZE_VERSION_MAJOR})
set(CPACK_PACKAGE_VERSION_MINOR ${GITANALYZE_VERSION_MINOR})
set(CPACK_PACKAGE_VERSION_PATCH ${GITANALYZE_VERSION_PATCH})
set(CPACK_PACKAGE_VERSION ${PACKAGE_VERSION})
set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/LICENSE")
set(CPACK_PACKAGE_DESCRIPTION "Git Analyze")
set(CPACK_DEBIAN_PACKAGE_DEPENDS "libc6 (>= 2.3.1-6)")
set(CPACK_PACKAGE_CONTACT "admin@oschina.cn")
set(CPACK_DEBIAN_PACKAGE_SECTION T)
if(WIN32 AND NOT UNIX)
  set(CPACK_PACKAGE_INSTALL_REGISTRY_KEY "GitAnalyze")
  set(CPACK_NSIS_MUI_ICON "${CMAKE_CURRENT_SOURCE_DIR}\\\\cmake\\\\git.ico")
  set(CPACK_NSIS_MUI_UNIICON "${CMAKE_CURRENT_SOURCE_DIR}\\\\cmake\\\\git.ico")
  set(CPACK_NSIS_MODIFY_PATH "ON")
  set(CPACK_NSIS_ENABLE_UNINSTALL_BEFORE_INSTALL "ON")
  if(CMAKE_CL_64)
    set(CPACK_NSIS_INSTALL_ROOT "$PROGRAMFILES64")
  endif()
endif()

include(CPack)

if(WIN32)
  include(InstallRequiredSystemLibraries)
endif()

option(USE_SANITIZE "Use address sanitizer compile git-analyze" OFF)
option(ENABLE_AZE_CLAR "Enable build aze test utils" OFF)

message(STATUS "Build git-analyze on ${CMAKE_SYSTEM_NAME} ")

set(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin)
set(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/lib)

# Need CMake 3.10 or Later https://cmake.org/cmake/help/v3.10/prop_tgt/CXX_STAND ARD.html#prop_tgt:CXX_STANDARD
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED YES)

if(MSVC)
  add_compile_options("-D_CRT_SECURE_NO_WARNINGS=1")
  add_compile_options("-Zc:__cplusplus") # C++ __cplusplus
  set(WIN_COMPILER_FLAGS
      CMAKE_CXX_FLAGS
      CMAKE_CXX_FLAGS_DEBUG
      CMAKE_CXX_FLAGS_RELEASE
      CMAKE_C_FLAGS
      CMAKE_C_FLAGS_DEBUG
      CMAKE_C_FLAGS_RELEASE)
  foreach(WIN_COMPILER_FLAG ${WIN_COMPILER_FLAGS})
    string(REPLACE "/MD" "/MT" ${WIN_COMPILER_FLAG} "${${WIN_COMPILER_FLAG}}")
  endforeach()
else()
  add_compile_options("-g")
  add_compile_options("-Wall")
  add_compile_options("-Wextra")
  if(USE_SANITIZE)
    add_compile_options("-fsanitize=address")
    add_compile_options("-fno-omit-frame-pointer")
    set(CMAKE_EXE_LINKER_FLAGS "-fsanitize=address ")
  endif()
endif()

set(ANALYZE_CLEANROOT "${CMAKE_BINARY_DIR}/cleanroot")

message(STATUS "TRACE '${CMAKE_GENERATOR}' ${CMAKE_MAKE_PROGRAM}")

include(ExternalProject)
include(FetchContent) # cmake 3.11 or Later

# Absl
set(ABSL_REPO https://github.com/abseil/abseil-cpp.git)
set(ABSL_TAG dc969f34a79d019497abb61c2a3f79b5b4be2ea9)

# Libgit2
set(LIBGIT2_URL https://github.com/libgit2/libgit2/archive/v1.0.1.tar.gz)
set(LIBGIT2_HASH 1775427a6098f441ddbaa5bd4e9b8a043c7401e450ed761e69a415530fea81d2)

# libre2
set(RE2_URL https://github.com/google/re2/archive/2020-08-01.tar.gz)
set(RE2_HASH 6f4c8514249cd65b9e85d3e6f4c35595809a63ad71c5d93083e4d1dcdf9e0cd6)
# libuv
set(LIBUV_URL https://github.com/libuv/libuv/archive/v1.38.1.tar.gz)
set(LIBUV_HASH 2177fca2426ac60c20f654323656e843dac4f568d46674544b78f416697bd32c)

set(LIBGIT2_LIBS git2)
set(AZE_UNIX_LIB)

if(WIN32)
  set(AZE_BUILD_TYPE ${CMAKE_BUILD_TYPE})
  set(LIBGIT2_LIBS
      git2
      ws2_32
      winhttp
      rpcrt4
      crypt32
      ole32)
  set(RE2_WIN_OPT -DCRT_FLAG_DEBUG=${CRT_FLAG_DEBUG} -DCRT_FLAG_RELEASE=${CRT_FLAG_RELEASE})

  # Fetch libuv
  FetchContent_Declare(
    libuv
    URL ${LIBUV_URL}
    URL_HASH SHA256=${LIBUV_HASH})
  FetchContent_GetProperties(libuv)
  if(NOT libuv_POPULATED)
    message(STATUS "Fetch content libuv ...")
    FetchContent_Populate(libuv)
    message(STATUS "Add include dir ${libuv_SOURCE_DIR}/include ...")
    include_directories("${libuv_SOURCE_DIR}/include")
    add_subdirectory("${libuv_SOURCE_DIR}")
  endif()
else()
  set(AZE_BUILD_TYPE Release)
  set(LIBGIT2_LIBS git2 z -static-libstdc++ -static-libgcc)
  set(AZE_UNIX_LIB pthread)
  ExternalProject_Add(
    libuv
    URL ${LIBUV_URL}
    URL_HASH SHA256=${LIBUV_HASH}
    CMAKE_ARGS -G${CMAKE_GENERATOR}
               -DCMAKE_BUILD_TYPE:STRING=${AZE_BUILD_TYPE}
               -DCMAKE_INSTALL_PREFIX:PATH=${ANALYZE_CLEANROOT}
               -DBUILD_SHARED_LIBS=OFF
               -DBUILD_TESTING=OFF
    BUILD_COMMAND cmake --build .
    INSTALL_COMMAND ${CMAKE_MAKE_PROGRAM} install)
endif()

set(UV_LIBS uv_a dl)

ExternalProject_Add(
  libgit2
  URL ${LIBGIT2_URL}
  URL_HASH SHA256=${LIBGIT2_HASH}
  PATCH_COMMAND patch -Nbp1 -i ${CMAKE_CURRENT_SOURCE_DIR}/patch/libgit2.patch
  CMAKE_ARGS -G${CMAKE_GENERATOR}
             -DCMAKE_C_COMPILER=${CMAKE_C_COMPILER}
             -DCMAKE_PROJECT_libgit2_INCLUDE=${CMAKE_CURRENT_SOURCE_DIR}/cmake/libgit2.cmake
             -DCMAKE_INSTALL_PREFIX:PATH=${ANALYZE_CLEANROOT}
             -DCMAKE_BUILD_TYPE:STRING=Release
  BUILD_COMMAND cmake --build .
  INSTALL_COMMAND ${CMAKE_MAKE_PROGRAM} install)

# build libre2
ExternalProject_Add(
  libre2
  URL ${RE2_URL}
  URL_HASH SHA256=${RE2_HASH}
  CMAKE_ARGS -G${CMAKE_GENERATOR}
             -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}
             -DCMAKE_CXX_FLAGS=${CMAKE_CXX_FLAGS}
             -DCMAKE_CXX_FLAGS_RELEASE=${CMAKE_CXX_FLAGS_RELEASE}
             -DCMAKE_CXX_FLAGS_DEBUG=${CMAKE_CXX_FLAGS_DEBUG}
             -DCMAKE_CXX_STANDARD=17
             -DCMAKE_BUILD_TYPE:STRING=${AZE_BUILD_TYPE}
             -DCMAKE_INSTALL_PREFIX:PATH=${ANALYZE_CLEANROOT}
             -DBUILD_SHARED_LIBS=OFF
             -DRE2_BUILD_TESTING=OFF
  BUILD_COMMAND cmake --build .
  INSTALL_COMMAND ${CMAKE_MAKE_PROGRAM} install)

FetchContent_Declare(
  absl
  GIT_REPOSITORY ${ABSL_REPO}
  GIT_TAG ${ABSL_TAG})

FetchContent_GetProperties(absl)
if(NOT absl_POPULATED)
  message(STATUS "Fetch content absl ${ABSL_TAG} ...")
  FetchContent_Populate(absl)
endif()

option(BUILD_TESTING "Force Disable Abseil Test" OFF)
add_subdirectory("${absl_SOURCE_DIR}")

include_directories(${ANALYZE_CLEANROOT}/include ${absl_SOURCE_DIR} ./include)

link_directories(${ANALYZE_CLEANROOT}/lib)

install(
  FILES "${ANALYZE_CLEANROOT}/share/libgit2/COPYING"
  DESTINATION share/libgit2
  RENAME copyright)

add_subdirectory(tools) # add tools
if(ENABLE_AZE_CLAR)
  add_subdirectory(test) # test
endif()
